﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection.Metadata;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Xml;

namespace WPFTools {
    public static class CommonFunc {
        // 得到的路径可能是文件夹
        public static List<string> GetPathListFromDragInRTB(RichTextBox rtbFileList) {
            List<string> pathList = new List<string>();
            foreach (Block blk in rtbFileList.Document.Blocks) {
                var para = blk as Paragraph;
                if (para == null) {
                    continue;
                }
                var run = para.Inlines.ElementAt(0) as Run;
                if (run == null) {
                    continue;
                }
                pathList.Add(run.Text);
            }
            return pathList;
        }

        public static List<string> GetFilePathListFromDragInRTB(RichTextBox rtbFileList, string filter) {
            List<string> listDirectoryPath = GetPathListFromDragInRTB(rtbFileList);
            var listResult = new List<string>();
            foreach (string path in listDirectoryPath) {
                var findResult = Directory.GetFiles(path, filter).FirstOrDefault();
                if (findResult == null) {
                    continue;
                }
                listResult.Add(findResult);
            }
            return listResult;
        }

        // 
        static string patternWithExpMarco = @"^([\t ]*)class[ ]+(\w+)[ ]+(\w+)"; // 替换已经设置了的导入导出宏
        static string patternWithOutExpMacro = @"^([\t ]*)class[ ]+(\w+)[ ]+:"; // 给没有设置导入导出宏的，且有继承的类设置导入导出宏
        static string patternWithOutExpMacroAndDerives = @"^([\t ]*)class[ ]+(\w+)[\t ]*(\r?)$"; // 给没有设置导入导出宏的，且没有继承的类设置导入导出宏。（末尾的\r?$是C#在处理\r\n结尾时需要特定的操作，所以在替换AS候也要把\r加回去，不然就不统一了）
        static string patternShareHeader = @"^[\t ]*#define[ ]+(\w+)[ ]+_declspec"; // 用于在 ShareHeader 里查找对应的宏名称
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rtbLog"></param>
        /// <param name="projectNameWithCode">不要后缀名</param>
        /// <param name="headerFilePaths"></param>
        /// <returns></returns>
        public static bool ProcessNewCreatedProjectHeaderFile(RichTextBox rtbLog, string projectNameWithCode, List<string> headerFilePaths) {
            #region 更改导入导出宏，以及给没有添加导入导出宏的类添加
            foreach (string headerFilePath in headerFilePaths) {
                if (!File.Exists(headerFilePath)) {
                    Logger.WriteLog($"后处理头文件 {Path.GetFileNameWithoutExtension(headerFilePath)}.h 时获取项目主类失败，找不到文件“{headerFilePath}”！\n", rtbLog, Colors.Yellow);
                    return false;
                }
                string projectFileContent = File.ReadAllText(headerFilePath, Encoding.GetEncoding("gb2312"));
                // 获取宏（虽然可以直接通过项目名推测，但还是通过ShareHeader读取把）
                string shareHeaderPath = $"{Path.GetDirectoryName(headerFilePath)}/{projectNameWithCode}ShareHeader.h";
                if (!File.Exists(shareHeaderPath)) {
                    Logger.WriteLog($"后处理项目 {projectNameWithCode} 时获取项目ShareHeader失败，找不到路径“{shareHeaderPath}”！\n", rtbLog, Colors.Yellow);
                    break;
                }
                string shareHeaderContent = File.ReadAllText(shareHeaderPath, Encoding.GetEncoding("gb2312"));
                // 
                var match = Regex.Match(shareHeaderContent, patternShareHeader, RegexOptions.Multiline);
                string macroToBeAdd = "";
                if (match.Success) {
                    macroToBeAdd = match.Groups[1].Value;
                }
                else {
                    Logger.WriteLog($"后处理项目 {projectNameWithCode} 时获取宏失败！\n", rtbLog, Colors.Yellow);
                    break;
                }
                // 通过正则替换
                projectFileContent = Regex.Replace(projectFileContent, patternWithExpMarco, @$"$1class {macroToBeAdd} $3", RegexOptions.Multiline);
                projectFileContent = Regex.Replace(projectFileContent, patternWithOutExpMacro, @$"$1class {macroToBeAdd} $2 :", RegexOptions.Multiline);
                projectFileContent = Regex.Replace(projectFileContent, patternWithOutExpMacroAndDerives, @$"$1class {macroToBeAdd} $2$3", RegexOptions.Multiline);
                // Include SHareHeader.h
                // 查找最后一个Include，作为插入点
                var includeMatches = Regex.Matches(projectFileContent, @"^[ ]*#include[ ]*"".+""", RegexOptions.Multiline);
                if (includeMatches.Count == 0) {
                    Logger.WriteLog($"后处理项目 {projectNameWithCode} 时查找ShareHeader插入点失败，跳过后处理！\n", rtbLog, Colors.Yellow);
                    break;
                }
                var lastIncludeMatchResult = includeMatches[includeMatches.Count - 1].Value;
                int insertPoint = projectFileContent.IndexOf(lastIncludeMatchResult) + lastIncludeMatchResult.Length;
                // 先查找，如果找得到就跳过
                if (projectFileContent.IndexOf($"{Path.GetFileName(shareHeaderPath)}") >= 0) {
                    Logger.WriteLog($"后处理项目 {projectNameWithCode} 时查找ShareHeader失败，已存在！跳过添加ShareHeader的步骤！\n", rtbLog, Colors.Yellow);
                }
                else {
                    projectFileContent = projectFileContent.Insert(insertPoint, $"\r\n#include \"{Path.GetFileName(shareHeaderPath)}\"");
                    Logger.WriteLog($"已为 {projectNameWithCode} 添加ShareHeader！\n", rtbLog, Colors.Green);
                }
                // 顺便添加一下resource.h
                // 先确认有没有IDD的资源定义
                if (projectFileContent.IndexOf("resource.h") >= 0) {
                    Logger.WriteLog($"后处理项目 {projectNameWithCode} 时发现已有Resource.h，跳过该步骤！\n", rtbLog, Colors.Yellow);
                }
                else {
                    var iddMatch = Regex.Match(projectFileContent, @"IDD = IDD_\w+");
                    if (iddMatch.Success) {
                        projectFileContent = projectFileContent.Insert(insertPoint, $"\r\n#include \"resource.h\"");
                        Logger.WriteLog($"后处理项目 {projectNameWithCode} 时发现IDD，已添加#include \"resource.h\"！\n", rtbLog, Colors.Green);
                    }
                }
                // 
                File.WriteAllText(headerFilePath, projectFileContent, Encoding.GetEncoding("gb2312"));
                #endregion
            }
            return true;
        }
        public static bool ProcessNewCreatedProjectHeaderFile(RichTextBox rtbLog, string projectPath) {
            string projectNameWithCode = Path.GetFileNameWithoutExtension(projectPath);
            string projectNameWithOutCode = Regex.Replace(projectNameWithCode, @"AP\d+_\d+_\d+", "");
            string mainHeaderFilePath = $"D:/VC/ObjectPRX 2024/inc/{projectNameWithOutCode}.h";
            // 检查三个字符串是否有空
            if (string.IsNullOrEmpty(projectNameWithCode) || string.IsNullOrEmpty(projectNameWithOutCode) || string.IsNullOrEmpty(mainHeaderFilePath)) {
                Logger.WriteLog($"项目名称等有空，请检查项目路径是否正确。\n\n", rtbLog);
            }
            else if (!File.Exists(mainHeaderFilePath)) {
                Logger.WriteLog($"项目头文件 {mainHeaderFilePath} 不存在，请检查项目路径是否正确。\n\n", rtbLog);
            }
            // TODO: 给之后的函数提供一个头文件列表，现在这里只提供单个，以后改为从项目文件获取头文件
            var listHeaderFilePaths = new List<string>();
            listHeaderFilePaths.Add(mainHeaderFilePath);

            return ProcessNewCreatedProjectHeaderFile(rtbLog, projectPath, listHeaderFilePaths);
        }
    }
}
